#ifndef ATTRIBUTE_H
#define ATTRIBUTE_H
#include <vector>
#include <iostream>
#include <algorithm>
#include <map>
#include <string>
#include <cstdlib>
#include "attribute_info.h"

class attribute
{
public:
	//==================================================
	// Construct
	//==================================================
    attribute ()
    {
        _missing = false;
        _id = 0;
        _attr_infos = NULL;
        _numeric = 0;
        _discrete = "";
    }
    //copy structor
    attribute (const attribute & other)
    {
        _missing = other._missing;
        _id = other._id;
        _attr_infos = other._attr_infos;
        _numeric = other._numeric;
        _discrete = other._discrete;
    }
//copy
    void copy (const attribute other)
    {
        _missing = other._missing;
        _id = other._id;
        _attr_infos = other._attr_infos;
        _numeric = other._numeric;
        _discrete = other._discrete;
    }

    bool same_with (const attribute& other)
    {
	if( _id != other._id)
		return false;
	if( _missing || other._missing)
		return false;

	if(type()==ATTR_DISCRETE)
	{
           if(_discrete == other._discrete)
	         return true;
	   else  
		 return false;
	}else{
           if(_numeric == other._numeric)
		   return true;
	   else 
		   return false;
	}
    }

    attribute (int id, string val, vector < attribute_info > *infos)
    {
        _missing = false;
        _attr_infos = infos;
        _id = id;

        if ( val == "?")
            _missing = true;
        else
        {
            if (type () == ATTR_NUMERIC)
                _numeric = atof (val.c_str ());
            if (type () == ATTR_DISCRETE)
                _discrete = val;
        }
    }
    //==============================================================
    // Print
    //==============================================================
    int print ()
    {
        cout << _id << "  ";
        if (type () == ATTR_NUMERIC)
            cout << "numeric" << "  ";
        if (type () == ATTR_DISCRETE)
            cout << "discrete" << "  ";
        if (_missing)
            cout << "mis" << "  ";
        else
            cout << "nomis" << "  ";

        if (type () == ATTR_NUMERIC)
            cout << _numeric << " " << endl;
        else
            cout << _discrete << " " << endl;

        return 0;
    }

    friend ostream& operator<<(ostream& os,const attribute& attr)
    {
	int type= attr._attr_infos->at(attr._id)._type;
        os << attr._id << "  ";
        if (type == ATTR_NUMERIC)
            os << "numeric" << "  ";
        if (type == ATTR_DISCRETE)
            os << "discrete" << "  ";

        if (attr._missing)
            os << "mis" << "  ";
        else
            os << "nomis" << "  ";

        if (type == ATTR_NUMERIC)
            os << attr._numeric << " " << endl;
        else
            os << attr._discrete << " " << endl;

        return os;
    }
//=========================================================================
//   Utiles
//=========================================================================
    bool missing ()
    {
        return _missing;
    }

    bool missing (bool fix)
    {
        _missing = fix;
        return _missing;
    }

    float numeric ()
    {
        return _numeric;
    }
    float numeric (float new_val)
    {
        _numeric = new_val;
        return _numeric;
    }

    
    string discrete ()
    {
        return _discrete;
    }
    string discrete (string fix)
    {
        _discrete = fix;
        return _discrete;
    }


     int type ()
    {
	   return  (*_attr_infos)[_id].type ();
	    }

    int set_attr_infos (vector < attribute_info > *info)
    {
        _attr_infos = info;
        return 0;
    }

    int id ()
    {
        return _id;
    }
    int id (int nid)
    {
        _id = nid;
        return _id;
    }


//=========================================================================
//  Member
//=========================================================================
    vector < attribute_info > *_attr_infos;
    bool _missing;
    int _id;
    float _numeric;
    string _discrete;
};
#endif
